#!/usr/bin/env python
# -*- coding: utf8 -*-

'''
Created on 2011-7-26

京东价格图片识别模块

@author: zhongfeng
'''

import ImageFilter, ImageChops
import Image
import re
import time

try:
    import psyco
    psyco.full()
except ImportError:
    pass

class CaptchaAlgorithm(object):
    '''captcha algorithm'''
    def LevenshteinDistance(self, m, n):
        c = [[i] for i in range(0, len(m) + 1)]
        c[0] = [j for j in range(0, len(n) + 1)]

        for i in range(0, len(m)):
            for j in range(0, len(n)):
                c[i + 1].append(
                    min(
                        c[i][j + 1] + 1,
                        c[i + 1][j] + 1,
                        c[i][j] + (0 if m[i] == n[j] else 1)
                    )
                )

        return c[-1][-1]

class CaptchaImageAlgorithm(object):
    '''captcha image algorithm'''
    @staticmethod
    def GetPixelsXEdges(im):
        pixels = im.load()
        xsize, ysize = im.size
        state = -1
        edges = []
        for x in xrange(xsize):
            weight = sum(1 if pixels[x, y] == 0 else 0 for y in xrange(ysize))
            level = 0
            if state == -1 and weight <= level:
                continue
            elif state == 1 and weight > level:
                continue
            else:
                state = -state
                edges.append(x)
        return [(edges[x], edges[x + 1]) for x in range(0, len(edges), 2)]

    @staticmethod
    def GetPixelsYEdges(im):
        pixels = im.load()
        xsize, ysize = im.size
        state = -1
        edges = []
        for y in xrange(ysize):
            weight = sum(1 if pixels[x, y] == 0 else 0 for x in xrange(xsize))
            level = 0
            if state == -1 and weight <= level:
                continue
            elif state == 1 and weight > level:
                continue
            else:
                state = -state
                edges.append(y)
        return [(edges[x], edges[x + 1]) for x in range(0, len(edges), 2)]

    @staticmethod
    def StripYEdge(im):
        yedges = CaptchaImageAlgorithm.GetPixelsYEdges(im)
        y1, y2 = yedges[0][0], yedges[-1][1]
        return im.crop((0, y1, im.size[0], y2))

    @staticmethod
    def GetBinaryMap(im):
        xsize, ysize = im.size
        pixels = im.load()
        return '\n'.join(''.join('#' if  pixels[x, y] == 0 else '_' for x in xrange(xsize)) for y in xrange(ysize))
    
    @staticmethod
    def getBitMapIn(im):
        xsize, ysize = im.size
        pixels = im.load()
        return tuple( 0 if  pixels[x, y] == 0 else 255 for x in xrange(xsize) for y in xrange(ysize))

class CaptchaProfile(object):
    def fiter(self, im):
        raise NotImplemented
    def split(self, im):
        raise NotImplemented
    def match(self, im):
        raise NotImplemented
    
def feature_to_data(feature):
    feature = re.sub(r'[\t\s]', '', feature)
    feature = re.sub(r'[\r\n]', '', feature)
    return tuple(0 if x == '#' else 255 for x in feature)

def captcha(filename, profile):
   
    #s = time.time()
    im = Image.open(filename)
    #s2 = time.time()
    #print 'open',s2-s
    im = profile.filter(im)
    #s3 = time.time()
    #print 'filter',s3 - s2 
    im_list = profile.split(im)
    #s4 = time.time()
    #print 'split',s4 - s3
    result = ''.join(profile.match(im) for im in im_list)
    #print 'match',time.time() - s4
    return result

